import { ESClassification } from "./ESClassification";
import { ESGeoExtrudedPolygon } from "./ESGeoExtrudedPolygon";
import { ESGeoPolygon } from "./ESGeoPolygon";
import { bind, extendClassProps, track, UniteChanged, JsonValue, createNextAnimateFrameEvent } from "xbsj-base";
import { ColorProperty, EnumProperty, BooleanProperty, GroupProperty, NumberProperty, ESJEditingMode } from "../../ESJTypes";
import { ESSceneObject } from "../base";


/**
 * https://c0yh9tnn0na.feishu.cn/docx/CKSfdDcwtoVPCtxgolkclEYZn9c
 */
export class ESHeightLimitAnalysis extends ESGeoPolygon {
    static override readonly type = this.register('ESHeightLimitAnalysis', this, { chsName: '控高分析', tags: ['ESObjects', '_ES_Impl_Cesium', '_ES_Impl_UE'], description: "控高分析对象" });
    override get typeName() { return 'ESHeightLimitAnalysis'; }
    override get defaultProps() { return ESHeightLimitAnalysis.createDefaultProps(); }
    override get json() { return this._innerGetJson() }
    override set json(value: JsonValue) { this._innerSetJson(value); }

    public override combinationClass: boolean = true;
    public override getMainClass(): ESSceneObject | undefined {
        return this._geoExtrudedPolygon;
    }

    static override supportEditingModes: string[] = [
        ...ESGeoPolygon.supportEditingModes,
        ESJEditingMode.HeightModify
    ];

    private _classification = this.dv(new ESClassification(`${this.id}_ESClassification`));//倾斜单体化
    get classification() { return this._classification; }
    private _geoExtrudedPolygon = this.dv(new ESGeoExtrudedPolygon(`${this.id}_ESGeoExtrudedPolygon`));//盒子
    get geoExtrudedPolygon() { return this._geoExtrudedPolygon; }

    override getESProperties() {
        const properties = { ...super.getESProperties() };
        return {
            ...properties,
            defaultMenu: 'basic',
            basic: [
                ...properties.basic,
                new NumberProperty('高度', '控高的高度', false, false, [this, 'height'], 10),
                new NumberProperty('最高高度', '最高高度', false, false, [this, 'maxHeight'], 200),
                new ColorProperty('超高颜色', '超高颜色', false, false, [this, 'overheightColor'], [1, 0, 0, 0.5]),
                new ColorProperty('标准颜色', '标准颜色', false, false, [this, 'standardColor'], [0, 1, 0, 0.5]),
            ], style: [
                new GroupProperty('点样式', '点样式集合', []),
                new BooleanProperty('开启', '开启点样式', false, false, [this, 'pointed'], false),
                new NumberProperty('点大小', '点大小(pointSize)', false, false, [this, 'pointSize'], 1),
                new EnumProperty('点类型', '点类型(pointSizeType)', false, false, [this, 'pointSizeType'], [['screen', 'screen'], ['world', 'world']], 'screen'),
                new ColorProperty('点颜色', '点颜色(pointColor)', false, false, [this, 'pointColor'], [1, 1, 1, 1]),

                new GroupProperty('线样式', '线样式集合', []),
                new BooleanProperty('开启', '开启线样式', false, false, [this, 'stroked'], false),
                new BooleanProperty('贴地', '是否贴地', false, false, [this, 'strokeGround'], false),
                new NumberProperty('线宽', '线宽(strokeWidth)', false, false, [this, 'strokeWidth'], 1),
                new EnumProperty('线类型', '线类型(strokeWidthType)', false, false, [this, 'strokeWidthType'], [['screen', 'screen'], ['world', 'world']], 'screen'),
                new ColorProperty('线颜色', '线颜色(strokeColor)', false, false, [this, 'strokeColor'], [1, 1, 1, 1]),

                new GroupProperty('面样式', '面样式集合', []),
                new BooleanProperty('开启', '开启填充样式', false, false, [this, 'filled'], true),
                new BooleanProperty('贴地', '是否贴地', false, false, [this, 'fillGround'], false),
                new ColorProperty('填充颜色', '填充颜色(fillColor)', false, false, [this, 'fillColor'], [1, 1, 1, 1]),
            ],
        }
    }
    override getProperties(language: string) {
        return [
            ...super.getProperties(language),
            new NumberProperty('高度', '控高的高度', false, false, [this, 'height'], 10),
            new NumberProperty('最高高度', '最高高度', false, false, [this, 'maxHeight'], 200),
            new ColorProperty('超高颜色', '超高颜色', false, false, [this, 'overheightColor'], [1, 0, 0, 0.5]),
            new ColorProperty('标准颜色', '标准颜色', false, false, [this, 'standardColor'], [0, 1, 0, 0.5]),
        ];
    }
    constructor(id?: string) {
        super(id);
        {
            this.d(this.components.disposableAdd(this._classification));
            this.d(this.components.disposableAdd(this._geoExtrudedPolygon));
        }

        {
            const { _classification, _geoExtrudedPolygon } = this;
            _geoExtrudedPolygon.perPositionHeight = true

            this.d(track([_classification, 'collision'], [this, 'collision']));
            this.d(track([_geoExtrudedPolygon, 'collision'], [this, 'collision']));

            this.d(bind([_geoExtrudedPolygon, 'editing'], [this, 'editing']));
            this.d(bind([_geoExtrudedPolygon, 'flyInParam'], [this, 'flyInParam']));
            this.d(bind([_geoExtrudedPolygon, 'flyToParam'], [this, 'flyToParam']));

            this.d(bind([_geoExtrudedPolygon, 'points'], [this, 'points']));
            this.d(bind([_geoExtrudedPolygon, 'extrudedHeight'], [this, 'height']));

            this.d(bind([_classification, 'fillColor'], [this, 'overheightColor']));
            this.d(bind([_geoExtrudedPolygon, 'fillColor'], [this, 'standardColor']));

            {
                const updatePos = () => {
                    const { height, points, maxHeight } = this
                    if (!points) return
                    const newArray = points.map(item => {
                        return [item[0], item[1], height];
                    }) as [number, number, number][]
                    _classification.points = newArray
                    _classification.height = maxHeight - height
                    if ((maxHeight - height) <= 0) {
                        _classification.show = false
                    } else {
                        _classification.show = this.show && this.filled
                    }
                }
                updatePos();
                const posEvent = this.dv(createNextAnimateFrameEvent(this.heightChanged, this.pointsChanged, this.maxHeightChanged))
                this.d(posEvent.don(updatePos));
            }
            {
                const update = () => {
                    const { show, filled } = this
                    _classification.show = show && filled
                    _geoExtrudedPolygon.show = show && filled
                }
                update();
                const event = this.dv(createNextAnimateFrameEvent(this.showChanged, this.filledChanged))
                this.d(event.don(update));
            }

            this.dispose(this.flyInEvent.don((duration?: number) => { _geoExtrudedPolygon.flyIn(duration); }));
            this.dispose(this.flyToEvent.don((duration?: number) => { _geoExtrudedPolygon.flyTo(duration); }));
            this.dispose(this.calcFlyToParamEvent.don(() => { _geoExtrudedPolygon.calcFlyToParam(); }));
            this.dispose(this.calcFlyInParamEvent.don(() => { _geoExtrudedPolygon.calcFlyInParam(); }));
        }
    }
}



export namespace ESHeightLimitAnalysis {
    export const createDefaultProps = () => ({
        height: 10,//高度
        maxHeight: 200,//最高高度
        overheightColor: [1, 0, 0, 0.5],//超高颜色
        standardColor: [0, 1, 0, 0.5],//标准颜色
        ...ESGeoPolygon.createDefaultProps(),
    });
}
extendClassProps(ESHeightLimitAnalysis.prototype, ESHeightLimitAnalysis.createDefaultProps);
export interface ESHeightLimitAnalysis extends UniteChanged<ReturnType<typeof ESHeightLimitAnalysis.createDefaultProps>> { }


